package hydrap2p.servicemanager;

import hydrap2p.ServiceLocation;
import hydrap2p.helper.Pinger;
import hydrap2p.servicemanager.listen.Listeners;

import java.util.Map;
import java.util.TreeMap;

import org.apache.thrift.TException;

public class ServiceController {

	private Map<String, ServiceLocation> locations;
	private Map<String, Pinger> pingers;
	
	public ServiceController()
	{
		locations=new TreeMap<String, ServiceLocation>();
		pingers=new TreeMap<String, Pinger>();

		Listeners.controller=this;
	}

	public void setServiceLocation(String arg0, ServiceLocation arg1) throws NameTaken {
		synchronized(locations)
		{
			if (locations.containsKey(arg0))
			{
				throw new NameTaken(arg0, locations.get(arg0));
			}
			
			locations.put(arg0, arg1);
			System.out.println("Registered "+arg0+" at "+arg1);
			Listeners.newService(arg0, arg1);

			if (pingers.containsKey(arg0))
			{
				pingers.get(arg0).shutdown();
				pingers.remove(arg0);
			}
			pingers.put(arg0, new ServicePinger(arg0, arg1));
		}
	}
	
	public void delServiceLocation(String arg0) {
		synchronized(locations)
		{
			if (locations.containsKey(arg0))
			{
				System.out.println("Unregistered "+arg0+" at "+locations.remove(arg0));
			}
			if (pingers.containsKey(arg0))
			{
				pingers.get(arg0).shutdown();
				pingers.remove(arg0);
			}
		}
		Listeners.delService(arg0);
	}

	public Map<String, ServiceLocation> getAllServiceLocations() {
		Map<String, ServiceLocation> ret;
		synchronized(locations)
		{
			ret=new TreeMap<String, ServiceLocation>(locations);
		}
		return ret;
	}

	public ServiceLocation getServiceLocation(String arg0) {
		synchronized(locations)
		{
			return locations.get(arg0);
		}
	}
	
	private class ServicePinger extends Pinger
	{
		public ServicePinger(String name, ServiceLocation location) {
			super(name, location);
		}

		@Override
		public void failure(String name) {
			System.out.println("Failed to ping "+name+", removing the stored location");
			delServiceLocation(name);
		}
		
	}
}
